<?php

class StatisticsController
{
    private $userModel;
    private $diaryAttachmentModel;
    private $statisticsModel;
    private $diaryListModel;
    private $commentModel;
    private $autoUidModel;
    private $rpcModel;
    private $feedModel;
    private $topicModel;
    private $groupInfoModel;
    private $diaryListCacheModel;
    private $attachmentModel;

    function __construct()
    {
        $this->userModel            =   new UserModel();
        $this->diaryAttachmentModel =   new DiaryAttachmentModel();
        $this->statisticsModel      =   new StatisticsModel();
        $this->diaryListModel       =   new DiaryListModel();
        $this->commentModel         =   new CommentModel();
        $this->autoUidModel         =   new AutoUidModel();
        $this->rpcModel             =   new RpcModel();
        $this->feedModel            =   new FeedModel();
        $this->topicModel          	=   new TopicModel();
        $this->groupInfoModel       =   new GroupInfoModel();
        $this->diaryListCacheModel  =   new DiaryListCacheModel();
        $this->attachmentModel      =   new AttachmentModel();
    }

    public function localDau($info)/*{{{*/
    {
        if (empty($info['uuid']))
        {
            exit ('uuid is empty!');
        }

        empty($info['device'])  &&  $info['device'] =   NULL;
        $result =   $this->statisticsModel->localDau($info);
        return  $result;
    }/*}}}*/

    public function apiStatistics($info)/*{{{*/
    {
        if (empty($info['do']))
        {
            return  FALSE;
        }

        $result =   $this->statisticsModel->apiStatistics($info);
        return  $result;
    }/*}}}*/

    public function snsDau($info)/*{{{*/
    {
        $result =   $this->statisticsModel->snsDau($info);
        return  $result;
    }/*}}}*/

    public function getSnsDau($info)/*{{{*/
    {
        if (empty($info['ymd']))    $begin  =   AC::SERVER_TIME;
        else    $begin  =   strtotime($info['ymd']);

        $endDay =   '20130115';
        $endTime=   strtotime($endDay);
        if ($begin  <   $endTime)           $begin  =   $endTime +  7 * 86400;
        if ($begin  >   AC::SERVER_TIME)    $begin  =   AC::SERVER_TIME;

        $result =   array();
        for ($i = 0; $i < 14; $i++)
        {
            $time   =   $begin  - $i * 86400;
            if ($time < $endTime)   break;
            $info['ymd']    =   date('Ymd', $time);

            $dayDau =   $this->statisticsModel->getSnsDau($info);
            if (empty($dayDau)  ||  !is_array($dayDau)) continue;

            $tmp['ymd'] =   $info['ymd'];
            foreach ($dayDau    as  $dau)
            {
                $tmp[$dau['stat']]  =   $dau['num'];
            }
            $result[]   =   $tmp;
            unset($tmp);
        }
        return  $result;
    }/*}}}*/

    public function getSnsQuarter($info)/*{{{*/
    {
        if (empty($info['ymd']))    $begin  =   AC::SERVER_TIME;
        else    $begin  =   strtotime($info['ymd']);

        $endDay =   '20130115';
        $endTime=   strtotime($endDay);
        if ($begin  <   $endTime)           $begin  =   $endTime +  7 * 86400;
        if ($begin  >   AC::SERVER_TIME)    $begin  =   AC::SERVER_TIME;

        empty($info['type'])    &&  $info['type']   =   'times';

        $resultTmp  =   array();
        $resultAll  =   array();
        for ($i = 0; $i < 14; $i++)
        {
            $time   =   $begin  - $i * 86400;
            if ($time < $endTime)   break;
            $info['ymd']    =   date('Ymd', $time);

            $quarter=   $this->statisticsModel->getSnsQuarter($info);
            if (empty($quarter) ||  !is_array($quarter))    continue;

            #   $tmp['Hour']    =   $info['ymd'];
            #   $all['Sum']     =   $info['ymd'];
            $tmp    =   array('Hour'=> $info['ymd'], NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
            $all    =   array('Sum' => $info['ymd'], NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
            $summation      =   0;
            foreach ($quarter   as  $value)
            {
                $tmp[$value['timeQuarter'] / 4] +=   $value['num'];
                if (empty($value['num']))   continue;
                $summation  =   $summation  +   $value['num'];
                $all[$value['timeQuarter'] / 4] =   $summation;
            }
            $resultTmp[]    =   $tmp;
            $resultAll[]    =   $all;
            unset($tmp);
            unset($all);
        }
        #   $resultTmp[]    =   array('<hr />', '按', '照', '时', '间', '段', '每', '时', '数', '量', '<hr />');
        #   $resultTmp[]    =   array('<hr />', '按', '照', '时', '间', '段', '累', '计', '数', '量', '<hr />');
        $result =   array_merge($resultTmp, $resultAll);
        return  $result;
    }/*}}}*/

    public function getTotalExchange($info)/*{{{*/
    {
        $result =   $this->statisticsModel->getTotalExchange($info);
        return  $result;
    }/*}}}*/

    public function getDailyExchange($info)/*{{{*/
    {
        $result =   $this->statisticsModel->getDailyExchange($info);
        return  $result;
    }/*}}}*/

    public function getExchangeList($info)/*{{{*/
    {
        $result =   $this->statisticsModel->getExchangeList($info);
        return  $result;
    }/*}}}*/
   
    public function getChosenDiary($info)/*{{{*/
    {
    	$category = isset($info['category'])  ?    intval($info['category']) :   0;
    	 
    	if($category > 0 && $category <  AC::DIARY_TAG_MAXID){
    		$result = $this->rpcModel->getChosenDiaryByCategory($info, $category);
    	}else{
	    	$result = $this->rpcModel->getChosenDiary($info);
	    	if(empty($result)){
	        	$result =   $this->statisticsModel->getChosenDiary($info);
	    	}
    	}
    	
        if (is_array($result))
        {
            foreach ($result   as  &$record)
            {
                $record['retweeted_status']  = $this->diaryListModel->manipulationListData($record);
                if (intval($record['rUid']) > 0 && intval($record['rBodyId']) > 0 && AC::$userVersion == '1'){
                    $record['abbreviation'] = $this->feedModel->iosRepostConnent($record);
                    if (!is_object($record['retweeted_status'])){
                        $record['attachmentPath'] = $record['retweeted_status']['attachmentPath'];
                    }
                }
                if (empty($record['attachmentPath']) || empty($record['eUid'])  ||  empty($record['bodyId']))   continue;
                $record['uid']              =   $record['eUid'];
                $attachment   =   $this->diaryAttachmentModel->getDiaryAllAttachment($record);
                // 添加了语音附件
                $record['attachmentList']    =    $attachment['attachmentList'];
                $record['voiceList']         =    $attachment['voiceList'];
                unset($record['uid']);
            }
        }
        return  $result;
    }/*}}}*/
    
    public function getHotDiary($info)/*{{{*/
    {
        $category = isset($info['category'])  ?    intval($info['category']) :   0;
    
        if($category > 0 && $category <  AC::DIARY_TAG_MAXID){
            $result = $this->rpcModel->getHotDiaryByCategory($info, $category);
        }else{
            $result = $this->rpcModel->getHotDiary($info);
        }
         
        if (is_array($result))
        {
            $diaryList = array();
            foreach ($result   as  &$record)
            {
               $diaryInfo  =  $this->diaryListModel->getDiaryInfoByBodyId($record);
                if (!empty($diaryInfo)){
                    $diaryInfo['id']    =    $diaryInfo['bodyId'];
                    $diaryList[] = $this->feedModel->square($diaryInfo);
                    continue;
                }
            }
        }
        
        // 版本判断，热门新的数据格式
        if (AC::$hotWidgetVersion == 1){
            if (empty($diaryList)) return (Object) array();
            
            $hottopic   = $this->getHotDiaryTopics($info['start']);
            $widgetInfo = $this->getWidgetInfoByPage($info);
            AC::$errorNo = null;
            $result = array(
                'status'    =>    $diaryList,
                'counts'    =>    count($diaryList),
                'widget'    =>    $widgetInfo,
                'hottopic'  =>    $hottopic
            );
            return  $result;
        }
        
        return $diaryList;
    }/*}}}*/
    
    /**
     * 根据页数返回扩展窗口信息
     * @param unknown $info
     * @return Ambigous <multitype:, Ambigous>
     */
    private function getWidgetInfoByPage ($info) {
        $start      =   isset($info['start'])  ?    $info['start'] :   0;
        $length     =   isset($info['length']) ?    $info['length']:   AC::DIARY_LIST_DEFAULT_LEN;
        // showConfig为页数的显示配置,热门话题显示在第二页,推荐用户显示在第三页
        $showConfig = array(
            'topic'     =>    array('page'  =>  1),
            'user'      =>    array('page'  =>  3)
        );
        // 避免同页出现
        if ($showConfig['toipc']['page'] == $showConfig['user']['page']){
            $showConfig['user']['page'] ++;
        }
        $widgetInfo         =     array();
        if (intval($info['category']) < 1){
            $widgetInfo     =     $this->getWidgetInfo($start, $length, $showConfig);
        }
        
        return $widgetInfo ? $widgetInfo : (Object) array();
    }
    
    /**
     * 获取热门点滴话题
     * @param unknown $start
     * @return StdClass|multitype:multitype:string  number multitype:Ambigous
     */
    private function getHotDiaryTopics ($start) {
        if ($start > 0) return (Object) array();
        
        $diaryTopics = $this->groupInfoModel->getDiaryTopics(AC::$diaryTopicCf['official'], 0, 0, 20);
        $topics = $this->groupInfoModel->loopGroupList($diaryTopics);
        $topics = array_slice($topics, 0, 5);
        if(empty($diaryTopics)) return (Object) array();
        
        $result = array(
            'topics' => $topics, 
            'count'  => count($topics),
            'more'   => array(
                "title"=> "点击查看更多话题",
                "action"=> "pinksns://diarytopic/list/hot"
            )
        );
        return $result;
    }
    
    /**
     * 获取热门窗口信息
     * @param unknown $start
     * @param unknown $length
     * @param unknown $showConfig
     * @return Ambigous <multitype:, number, StdClass>
     */
    private function getWidgetInfo($start, $length, $showConfig){
        $topicShowPage =  $showConfig['topic']['page'];
        $userShowPage  =  $showConfig['user']['page'];
        
        // 初始化数据
        $result =  $data  =  array();
        $data = array(
                'title'          =>    '精选话题',
                'widget_type'    =>    '1',
                'data_type'      =>    '2',
                'menus'          =>    array(),
                'header'         =>    array(
                        'title'    =>    '精选话题',
                        'action'   =>    ''
                ),
                'footer'          =>    array(
                        'title'    =>    '更多',
                        'action'   =>    'pinksns://group/list/my'
                ),
                'url_struct'     =>    array(),
                'feeds_counts'   =>    '0'
        );

        // 显示的页数判断，只在固定的页数显示
        if ($topicShowPage > 0 && $start >= ($topicShowPage - 1) * $length && $start < $topicShowPage * $length ){
            $result = $this->getTopicWidgetList($data, $topicShowPage, $start, $length);

        }elseif($userShowPage > 0 && $start >= ($userShowPage - 1) * $length && $start < $userShowPage * $length ){
            //$result = $this->getTUserWidgetList($data, $userShowPage, $start, $length);
            $result = array();
        }
        
        return $result;
    }
    
    /**
     * 获取推荐用户窗口
     * @param unknown $data
     * @return StdClass|number
     */
    private function getTUserWidgetList($data){
        // 获取推荐用户列表
        $uids         =    $this->diaryListCacheModel->recommentUserList(0 , 0, -1);
        $friends      =    $this->diaryListCacheModel->getFriendsList(AC::HOST_UID);
        $friends[]    =    AC::HOST_UID;
        $uids         =    array_diff($uids, $friends);
        $uids         =    UK::array_random_assoc($uids, 5);
        if (empty($uids)){
            return (Object) array();
        }
        
        // 初始化数据
        $data['title']              =    '推荐用户';
        $data['data_type']          =    '1';
        $data['header']['title']    =    '推荐用户';
        $data['header']['action']   =    'pinksns://channel/recommenduser';
        $data['footer']['action']   =    'pinksns://channel/recommenduser';
        
        $users = $tmp = array();
        foreach ($uids as $val){
            $userInfo = $this->autoUidModel->getUserInfo($val);
            $tmp = array(
                    'url_title'    =>    strval($userInfo['nickname']),
                    'url_content'  =>    strval($userInfo['signature']),
                    'url_image'    =>    strval($userInfo['avatar']),
                    'url_action'   =>    "pinksns://user/info?uid=".$val,
                    'url_type_id'  =>    strval($userInfo['uid']),
                    'url_type'     =>    "user",
                    'url_extend'   =>    $userInfo
            );
            $users[] = $tmp;
        }
        
        $data['url_struct']      =    $users;
        $data['feeds_counts']    =    count($data['url_struct']);
        return $data;
    }
    
    /**
     * 获取精华话题列表
     * @param unknown $data
     * @return multitype:|number
     */
    private function getTopicWidgetList($data){
//         $digestTopics = $this->topicModel->getDigestTopics(20);
        // 获取精华帖更新为获取推荐话题列表
        $digestTopics = $this->topicModel->getRecommendTopicList(0, 20);
        if (empty($digestTopics)){
            return array();
        }
        
        // 屏蔽掉无图片的话题
        $list_exist_attachment = $list_not_exist_attachment = array();
        foreach ($digestTopics as $value){
            $attachment = $this->attachmentModel->getAttachmentInfo(array('tid' =>$value['tid'], 'uid' => $value['uid'], 'pid' => 1));
            if (count($attachment['attachmentList']) > 0){
                $list_exist_attachment[] = $value;
            }else{
                $list_not_exist_attachment[] = $value;
            }
        }
        $digestTopics = array_slice(array_merge($list_exist_attachment, $list_not_exist_attachment), 0 , 3);
        
        $topics = $tmp = array();
        foreach ($digestTopics as $val){
            $topicInfo = $this->topicModel->topicAddRedis(array('tid' => $val['tid']));
            $groupInfo = $this->groupInfoModel->groupAddRedis($topicInfo['gid']);
            $tmp = array(
                    'url_title'    =>    strval($topicInfo['title']),
                    'url_content'  =>    strval($topicInfo['abbreviation']),
                    'url_image'    =>    strval($topicInfo['attachments'][0]['attachmentPath']),
                    'url_action'   =>    "pinksns://group/topic?tid=".$topicInfo['tid']."&uid=".$topicInfo['uid'],
                    'url_type_id'  =>    strval($topicInfo['tid']),
                    'url_type'     =>    "topic",
                    'url_extend'   =>    array(
                        'gid'    =>     strval($topicInfo['gid']),
                        'gname'  =>     strval($topicInfo['gname']),
                        'cover'  =>     strval($groupInfo['cover']),
                        'gAvatar'=>     strval($groupInfo['avatar']),
                        'res_num'=>     strval($topicInfo['response_num']),
                        'display'=>     strval($topicInfo['display']),
                        'digest' =>     strval($topicInfo['digest'])
                    )
            );
            $topics[] = $tmp;
        }
        
        $data['url_struct']      =    $topics;
        $data['feeds_counts']    =    count($data['url_struct']);
        return $data;
    }
    
    /**
     * 热门推荐日记
     * @param unknown $info
     * @return boolean|StdClass|multitype:Ambigous <string, mixed>
     */
    public function getHotRecommendDiary($info) {
        if (AC::$recommendIosVersion)
        {
            return $this->getHotRecommendDiaryIOS($info);
        }
        $host_uid = AC::HOST_UID;
        $more = 0;
        $startId = 0;
        isset($info['more']) && $more = intval($info['more']);
        isset($info['id']) && $startId = intval($info['id']);

        // 分页参数
        list($id, $start, $length) = UK::assemblePageData($info);
//        if ($more) $length = -1;

        // 登录用户根据标签推荐日记
        $list = array();
//        $list = $this->getDiaryListByTag($host_uid, $id, $length);
        $list = $this->diaryListCacheModel->getRecommendDianDiForUList(0, -1);
        $list = array_keys($list);
        if($list){
            if ($more) {//更多的处理
                $start = array_search($id, $list);
                if ($start===false){
                    $start = 0;
                }else{
                    $start = $start==0 ? $start : $start + 1;
                }
                $list  = array_slice($list, $start, $length);
            }else{
                if ($startId==0){//首页
                    $list  = array_slice($list, 0, $length);
                }else{//随机按钮
                    $list   = UK::array_random_assoc($list, $length);
                }
            }
        }else{//没有缓存时
            $list = $this->rpcModel->getHotDiaries($id, $length);
        }

        // 返回数据判断
        if (empty($list)) $list = [];

        if (!$more) {
            $diarys = $this->getDiaryItems($list);
            // 有附件的排到前面
            $diarys = $this->standingAttachmentInTheFront($diarys);
            $diarys = array_slice($diarys, 0, 5);
        }else{
            $diarys = $this->getDiaryItems($list);
        }
        
        
        $result = array(
            'status'    =>    $diarys,
            'counts'    =>    count($diarys),
            'widget'    =>    (Object) array()
        );
        return $result;
    }

    public function getHotRecommendDiaryIOS($info) {
        $host_uid = AC::HOST_UID;
        $more = 0;
        isset($info['more']) && $more = intval($info['more']);

        // 分页参数
        list($id, $start, $length) = UK::assemblePageData($info);
        if (empty($more)) $length = -1;

        // 登录用户根据标签推荐日记
        $list = array();
        if ($host_uid) {
            $list = $this->getDiaryListByTag($host_uid, $id, $length);
            if ($more && $list) {
                $start = array_search($id, $list) ;
                $start = $start + 1;
                $list  = array_slice($list, $start, $length);
            }
        }

        // 未登录用户或者未设置标签用户,防止数据为空
        if (empty($list) || empty($host_uid)){
            $list = $this->rpcModel->getHotDiaries($id, $length);
        }

        // 返回数据判断
        if (empty($list)) return (Object) array();

        if (empty($more)) {
            // 随机返回5个
            $list   = UK::array_random_assoc($list, 10);
            $diarys = $this->getDiaryItems($list);
            // 有附件的排到前面
            $diarys = $this->standingAttachmentInTheFront($diarys);
            $diarys = array_slice($diarys, 0, 5);
        }else{
            $diarys = $this->getDiaryItems($list);
        }


        $result = array(
            'status'    =>    $diarys,
            'counts'    =>    count($diarys),
            'widget'    =>    (Object) array()
        );
        return $result;
    }
    
    /**
     * 根据标签返回相关热门日记
     * @param unknown $uid
     * @return multitype:|boolean|Ambigous <multitype:, multitype:>
     */
    private function getDiaryListByTag ($uid, $id, $length) {
        if (empty($uid)) return array();
        
        // 获取用户信息
        $user = $this->userModel->getUserInfo($uid);
        if (empty($user)) {
            AC::$errorNo    =   'UC023';
            return  FALSE;
        }
        
        // redis的key的合集
        $list = array();
        $unionKeysArr = Tags::getUnionKeys(explode(',', $user['tags']));
        if ($unionKeysArr) {
            $list = $this->rpcModel->getHotRecommendDiary($id, $unionKeysArr, $length);
        }
        return $list;
    }
    
    private function getDiaryItems ($list) {
        if (empty($list)) return array();
        
        $result = array();
        foreach ($list as &$record)
        {
            $diaryInfo  =  $this->diaryListModel->getDiaryInfoByBodyId($record);
            if (!empty($diaryInfo)){
                $diaryInfo['id']    =    $diaryInfo['bodyId'];
                $diaryInfo['abbreviation'] = UK::cleanStr($diaryInfo['abbreviation']);
                $result[] = $this->feedModel->square($diaryInfo);
                continue;
            }
        }
        
        return $result;
    }
    
    private function standingAttachmentInTheFront ($list) {
        if (empty($list)) return array();
        
        $front = array();
        $behind = array();
        foreach ($list as $value) {
            if ($value['attachmentList']) {
                $front[] = $value;
            }else{
                $behind[] = $value;
            }
        }
        
        return array_merge($front, $behind);
    }
    
    public function getChosenByEditor($info = NULL)/*{{{*/
    {
        $result =   $this->statisticsModel->getChosenByEditor($info);
        return  $result;
    }/*}}}*/

    public function countChosenDiaryForScript($info = NULL)/*{{{*/
    {
        $hour       =   date('H', SERVER_TIME + 900);
        $periodType =   floor($hour / 6) + 1;
        $timesHour  =   floor($hour / 3);
        if ($timesHour % 2) $timesType  =   'likeTimes';
        else    $timesType  =   'commentTimes';

        $minute     =   date('i', SERVER_TIME + 900);
        $topMinute  =   floor($minute / 15);
        $insertIndex=   $topMinute % 2;

        $info['periodType'] =   $periodType;
        $info['timesType']  =   $timesType;

        $this->statisticsModel->removeChosenDiary($insertIndex);

        for ($i =0; $i < 32; $i++)
        {
            $this->commentModel->countCommentPeople($i);
            sleep(1);
            $this->diaryListModel->countCommentPeople($i);
            sleep(1);
            echo $i, "\t";

            $info['index']      =   $i;
            $info['timesType']  =   'grossScore';
            $top20  =   $this->statisticsModel->countChosenDiary($info);
            if (!empty($top20)  &&  is_array($top20))
            {
                $top20  =   $this->matchNickname($top20);
                $this->statisticsModel->setChosenDiary($top20, $insertIndex);
            }

            $info['timesType']  =   'likeTimes';
            $top20  =   $this->statisticsModel->countChosenDiary($info);
            if (empty($top20)   ||  !is_array($top20))  continue;
            $top20  =   $this->matchNickname($top20);
            $this->statisticsModel->setChosenDiary($top20, $insertIndex);

            $info['timesType']  =   'commentTimes';
            $top20  =   $this->statisticsModel->countChosenDiary($info);
            if (empty($top20)   ||  !is_array($top20))  continue;
            $top20  =   $this->matchNickname($top20);
            $this->statisticsModel->setChosenDiary($top20, $insertIndex);
        }
        return  TRUE;
    }/*}}}*/

    private function matchNickname($top20)/*{{{*/
    {
        $nicknames  =   array();

        foreach ($top20 as  &$record)
        {
            if (empty($record['nickname'])) continue;

            if (!isset($nicknames[$record['nickname']]))
            {
                $userBaseInfo   =   $this->autoUidModel->getUserInfo($record['uid']);
                if (!isset($userBaseInfo['nickname']))   continue;
                $nicknames[$record['uid']]  =   $userBaseInfo['nickname'];
            }

            $record['nickname'] =   $nicknames[$record['uid']];
        }
        return  $top20;
    }/*}}}*/

}

